﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.IO;
using System.Text;
using System.Windows.Forms;
using MapXLib;
using Point = System.Drawing.Point;
using Rectangle = MapXLib.Rectangle;

namespace MapControl
{
    public enum DrawToolType
    {
        None,
        Distance,
        Pointer,
        Rectangle,
        Ellipse,
        Line,
        Polygon,
        GridRegion,
        NumberOfDrawTools
    };

    public partial class ucMap : UserControl
    {
        //*****************************************************
        //Draw grid to create 9x9 Coordinate
        private Coordinate9x9 _coord9x9;
        private bool showCoordinate9x9;

        //Cho biết map hiển thị review hay đang nhận dữ liệu trực tiếp từ cổng COM
        private bool _isReview;

        public DrawToolType ActiveTool;
        
        /// <summary>
        /// Active drawing tool.
        /// </summary>
        public AxMapXLib.AxMap Map
        {
            get
            {
                return AxMap1;
            }
        }

        /// <summary>
        /// Show 9x9 coordinate
        /// </summary>
        public bool ShowCoordinate9x9
        {
            get
            {
                return showCoordinate9x9;
            }
            set
            {
                showCoordinate9x9 = value;
            }
        }

        /// <summary>
        /// Show 9x9 coordinate
        /// </summary>
        public Coordinate9x9 Coord9x9
        {
            get
            {
                return _coord9x9;
            }
            set
            {
                _coord9x9 = value;
            }
        }

        /// <summary>
        /// Khoảng cách zoom hiển thị bản đồ (đơn vị là km)
        /// </summary>
        public double Altitude
        {
            get
            {
                return AxMap1.Zoom / 1000;
            }
        }

        public ucMap()
        {
            InitializeComponent();
            InitMap();
            _coord9x9 = new Coordinate9x9(this);
        }

        public ucMap(bool isReview)
        {
            InitializeComponent();
            InitMap();
            _coord9x9 = new Coordinate9x9(this);
            _isReview = isReview;
        }

        public void InitMap()
        {
            //Cho phép dùng scroll để thu phóng bản đồ
            AxMap1.MousewheelSupport = MapXLib.MousewheelSupportConstants.miMousewheelNoAutoScroll;
            //AxMap1.MousewheelSupport = MapXLib.MousewheelSupportConstants.miFullMousewheelSupport;//.miNoMousewheelSupport;//.miMousewheelNoAutoScroll;
            AxMap1.GeoSet = string.Format(@"{0}\Maps\BanDo.gst", Application.StartupPath);
            AxMap1.Title.Visible = false;
            
            
            AxMap1.CurrentTool = MapXLib.ToolConstants.miArrowTool;
            AxMap1.NumericCoordSys = AxMap1.DisplayCoordSys;
            AxMap1.PaperUnit = MapXLib.PaperUnitConstants.miPaperUnitPoint;
            AxMap1.MapUnit = MapXLib.MapUnitConstants.miUnitMeter;//.miUnitKilometer;
            AxMap1.Layers.AddUserDrawLayer("Symbols", 1);

            ViewDefaultMap();

            //double x = AxMap1.Layers["Symbols"].CoordSys.Bounds.XMin;
            //double y = AxMap1.Layers["Symbols"].CoordSys.Bounds.YMin;

            //double zoom = AxMap1.Zoom;
            //double cX = AxMap1.CenterX;
            //double cY = AxMap1.CenterY;
            //AxMap1.CreateCustomTool(3, MapXLib.ToolTypeConstants.miToolTypePoint,
            //                            MapXLib.CursorConstants.miArrowQuestionCursor);
        }

        public override void Refresh()
        {
            //AxMap1.Invalidate(new System.Drawing.Rectangle(0, 0, 500, 500));  
            //AxMap1.Layers["Symbols"].Refresh();
            //AxMap1.Layers["Symbols"].Invalidate(true);
            AxMap1.Refresh();
            
        }

        

        /// <summary>
        /// Hiển thị bản độ theo cấu hình mặc định ban đầu
        /// </summary>
        public void ViewDefaultMap()
        {
            AxMap1.ZoomTo(3206118, 106.9284196519465, 16.07934787370213);
        }

        private PointF mouseDownPoint;
        private PointF mouseMovePoint;
        public event AxMapXLib.CMapXEvents_MouseDownEventHandler AxMap_MouseDownEvent;
        private void AxMap1_MouseDownEvent(object sender, AxMapXLib.CMapXEvents_MouseDownEvent e)
        {
            mouseDownPoint = new PointF(e.x, e.y);
            if (AxMap_MouseDownEvent != null)
                AxMap_MouseDownEvent(sender, e);

            //if left mouse click
            if (e.button == 1)
            {
                   
            }
            else if (e.button == 2)
            {
                //Nếu đang ở kéo bản đồ thì chuyển sang mũi tên
                if (AxMap1.CurrentTool == MapXLib.ToolConstants.miPanTool)
                {
                    AxMap1.CurrentTool = MapXLib.ToolConstants.miArrowTool;
                }

                if (ActiveTool == DrawToolType.Distance)
                    ActiveTool = DrawToolType.None;
            }
            
        }

        public event AxMapXLib.CMapXEvents_MouseMoveEventHandler AxMap_MouseMoveEvent;
        private void AxMap1_MouseMoveEvent(object sender, AxMapXLib.CMapXEvents_MouseMoveEvent e)
        {
            //Nếu đang nhấn chuột trái mà move
            if (e.button == 1)
            {
                if (ActiveTool == DrawToolType.None)
                {
                    mouseMovePoint = new PointF(e.x, e.y);

                    //Nếu đang ở tool mũi tên và nhấn giữ chuột trái di chuyển > 100 pixel thì chuyển sang PAN
                    if (AxMap1.CurrentTool == MapXLib.ToolConstants.miArrowTool
                        && CalculateDistance(mouseDownPoint, mouseMovePoint, enumDistance.Pixel) > 100)
                    {
                        AxMap1.CurrentTool = MapXLib.ToolConstants.miPanTool;

                    }
                }
            }
            if (AxMap_MouseMoveEvent != null)
                AxMap_MouseMoveEvent(sender, e);
            
            //UpdateToolStrip(e.x, e.y);
        }


        public event AxMapXLib.CMapXEvents_MouseUpEventHandler AxMap_MouseUpEvent;
        private void AxMap1_MouseUpEvent(object sender, AxMapXLib.CMapXEvents_MouseUpEvent e)
        {
            //Point pScreen = new Point((int)e.x, (int)e.y);
            if (AxMap_MouseUpEvent != null)
                AxMap_MouseUpEvent(sender, e);
           
        }

            
        public event AxMapXLib.CMapXEvents_DrawUserLayerEventHandler AxMap_DrawUserLayer;
        private void AxMap1_DrawUserLayer(object sender, AxMapXLib.CMapXEvents_DrawUserLayerEvent e)
        {
            if (AxMap_DrawUserLayer != null)
                AxMap_DrawUserLayer(sender, e);

            Graphics myGraphics = Graphics.FromHdc(new IntPtr(e.hOutputDC));
            //9x9 coordinate
            _coord9x9.Init();
            if (showCoordinate9x9)
                _coord9x9.Draw(myGraphics);

            myGraphics.Dispose();
        }

        public event AxMapXLib.CMapXEvents_MouseWheelEventHandler AxMap_MouseWheelEvent;
        private void AxMap1_MouseWheelEvent(object sender, AxMapXLib.CMapXEvents_MouseWheelEvent e)
        {
            Refresh();
            //UpdateToolStrip(e.x, e.y);
        }

        public enum enumDistance
        {
            Pixel,
            Kilometer
        }

        /// <summary>
        /// Tính khoảng cách tọa độ
        /// </summary>
        /// <param name="pointForm"></param>
        /// <param name="pointTo"></param>
        /// <param name="eDistance"></param>
        /// <returns></returns>
        public double CalculateDistance(PointF pointForm, PointF pointTo, enumDistance eDistance)
        {
            double distance = 0;
            float x1, y1, x2, y2;
            x1 = pointForm.X;
            y1 = pointForm.Y;
            x2 = pointTo.X;
            y2 = pointTo.Y;
            //Nếu cần tính khoảng cách theo kilomet
            if (eDistance == enumDistance.Kilometer)
            {
                double lon1, lat1, lon2, lat2;
                lon1 = lat1 = lon2 = lat2 = 0;
                //AxMap1.ConvertCoord(ref pointForm.X, ref pointForm.Y, ref lon1, ref lat1, MapXLib.ConversionConstants.miScreenToMap);
                //AxMap1.ConvertCoord(ref pointTo.X, ref pointTo.Y, ref lon2, ref lat2, MapXLib.ConversionConstants.miMapToScreen);
                AxMap1.ConvertCoord(ref x1, ref y1, ref lon1, ref lat1, MapXLib.ConversionConstants.miScreenToMap);
                AxMap1.ConvertCoord(ref x2, ref y2, ref lon2, ref lat2, MapXLib.ConversionConstants.miScreenToMap);
                distance = AxMap1.Distance(lon1, lat1, lon2, lat2)/1000;
            }
            else //Nếu tính khoảng cách theo pixel
            {
                distance = Math.Sqrt(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2));
            }
            return distance;
        }
    }
}
